package graphics.image 
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.filters.GlowFilter;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import graphics.raster.ComponentLabelling;
	/**
	 * @author Nicolas Barradeau
	 * http://en.nicoptere.net
	 */
	public class Outline
	{
		static private var bd:BitmapData;
		static private var origin:Point = new Point();
		static private var points:Vector.<Point>;
		
		public function Outline() 
		{
		}
		
		static public function process( source:BitmapData ):Vector.<Point> 
		{
			
			
			var bds:Vector.<Bitmap> = ComponentLabelling.process( source );
			if ( bds == null ) return null;
			
			bd = new BitmapData( source.width, source.height, true, 0 );
			points = Vector.<Point>([]);
			
			
			for each( var bmp:Bitmap in bds )
			{
				
				bd.draw( bmp, new Matrix( 1,0,0,1, bmp.x, bmp.y ) );
				
				bd.applyFilter( source, source.rect, origin, new GlowFilter( 0xFF0000, 1, 1.1, 1.1, 1, 3, true, true ) );
				bd.threshold( bd, bd.rect, origin, '>', 0, 0xFFFFFFFF );
				
				
				var start:Point = getFirstNonTransparentPixel( bd );
				
				if ( start == null )continue;
				
				addSite( start );
				
			}
			
			return points;
			
		}
		
		static private function addSite( p:Point ):void
		{
			
			bd.setPixel32( p.x, p.y, 0 );
			points.push( p );
			
		}
		
		static public function getFirstNonTransparentPixel( bmd:BitmapData ):Point
		{
			var hit_rect:Rectangle=new Rectangle(0,0,bmd.width,1);
			var hit_bmd:BitmapData=new BitmapData( bmd.width, 1, true, 0 );
			var p:Point = new Point();
			for ( hit_rect.y = 0; hit_rect.y < bmd.height; hit_rect.y++ )
			{
				if ( bmd.hitTest( p, 0x01, hit_rect) )
				{
					hit_bmd.copyPixels( bmd, hit_rect, p );
					return hit_rect.topLeft.add( hit_bmd.getColorBoundsRect(0xFF000000, 0, false).topLeft );
				}
			}
			return null;
		}
		
		static public function get bitmapData():BitmapData { return bd; }
		
		static public function set bitmapData(value:BitmapData):void 
		{
			bd = value;
		}
		
	}

}